﻿using System;
using System.Collections.Generic;
using System.Linq;
using Gp.Scripts.Core;
using QFramework;
using UnityEngine;

namespace Gp.Scripts.Core
{
    public class MainArchitecture : Architecture<MainArchitecture>
    {
        public readonly Dictionary<string, PersistentModel> PersistentModels = new();


        protected override void Init() { }


        public T BuildMonoManager<T>(string name = "Manager") where T : Component
        {
            var obj = new GameObject(name);
            obj.transform.SetParent(GameEntry.Instance.transform);
            return obj.AddComponent<T>();
        }


        public void RegisterConfig(ISystemConfig systemConfig)
        {
            CommonUtils.SafeCall(systemConfig.Load, "MainArchitecture.RegisterConfig", "Error when loading config");
            // todo: 应用其他IStructure 类的type 参数
            Type iocType =
                systemConfig.GetType().GetCustomAttributes(false).OfType<AutoLoadAttribute>().FirstOrDefault()?.IOC_Type ??
                systemConfig.GetType();
            if (!iocType.IsAssignableFrom(systemConfig.GetType()))
            {
                Debug.LogError($"[MainArchitecture]: 类型对应错误, {systemConfig.GetType()} 不能为 {iocType}");
                return;
            }
            mContainer.RegisterByType(systemConfig, iocType);
        }

        public void RegisterByType(IStructure obj, Type type)
        {
            mContainer.RegisterByType(obj, type);
        }
        

        // public TConfig GetConfig<TConfig>() where TConfig : class, ISystemConfig
        // {
        //     return mContainer.Get<TConfig>();
        // }

        public T Get<T>() where T : class
        {
            return mContainer.Get<T>();
        }

        public void RegisterData<T>(T systemData) where T : BaseSystemData
        {
            this.mContainer.Register(systemData);
        }
    }

    public interface ISystemConfig : IStructure
    {
        void Load();
    }

    public interface IConfigTable { }

    public class AbstractConfigTable : IConfigTable{ } 

    public abstract class SystemSystemConfig : ISystemConfig
    {
        public void Load()
        {
            OnLoad();
        }

        protected virtual void OnLoad() { }
    }


    public enum ConfigGroup
    {
        City,
        Level,
    }


    [AttributeUsage(AttributeTargets.Class, Inherited = false)]
    public class AutoLoadAttribute : Attribute
    {
        public Type IOC_Type = null;
        public AutoLoadAttribute() { }

        public AutoLoadAttribute(Type iocType)
        {
            IOC_Type = iocType;
        }
    }


    public interface IStructure { }


    public abstract class PersistentModel : AbstractModel
    {
        public abstract ISerializedModel OnSave();

        public abstract void OnLoad(ISerializedModel model);
    }


    public abstract class PersistentModel<T> : PersistentModel where T : ISerializedModel
    {
        public override void OnLoad(ISerializedModel model)
        {
            if (model == null) return;
            OnLoad(model as T);
        }

        protected abstract void OnLoad(T data);
    }
}